﻿#ifndef LECALIBRATOR_H
#define LECALIBRATOR_H
#include <gsl/gsl_interp.h>
#include <QVector>
/**
 * @brief The LECalibrator class 光栅尺（Linear Encoder）输出位移修正器。
 *                               由于各种原因，导致光栅尺的测量结果与真实值有一定的差距。
 *                               本 C++类可以对光栅尺的测量结果进行一定程度的修正。
 * 要求校准点之间的真实距离是 1mm 的整数倍，比如有如下校准点： 4.002 6.01  7.003 9.031 15.03
 * 那么程序默认6.01 到 4.002 的距离是 2mm, 7.003 到 4.002 的距离是 3mm, 9.031 到4.002 的距离是 5mm
 * 并以此为依据来修正其他的点。其中最小的点保持不变，也就是 4.002 修正后的结果还是 4.002,
 * 那么 9.031 修正的结果是 9.002.
 */
class LECalibrator
{
public:
    LECalibrator();
    ~LECalibrator();

    /**
     * @brief loadPoints 将校准点传入
     * @param points 校准点，要求这些校准点之间的真实距离是 1mm 的整数倍。校正点不需要排序，程序内部会自动排序。
     *                校准点也不需要是等间隔的，但是从修正效果考虑，建议为实际距离等间隔点
     */
    void loadPoints(QVector<double> points);

    void loadPoints(double p[], int N);
    /**
     * @brief encoderPosToTruePos 对光栅尺的结果进行修正
     * @param value 光栅尺的原始数值
     * @return 修正后的数值
     */
    double encoderPosToTruePos(double value);
    double truePosToEncoderPos(double value);
    void print();/// 测试用
private:
    void reset();
    void build();
    gsl_interp * m_interp;
    gsl_interp * m_interp_rev;
    gsl_interp_accel * m_accel;
    gsl_interp_accel * m_accel_rev;
    double * m_xa;
    double * m_ya;
    int m_size;
};

#endif // LECALIBRATOR_H
